export type DebounceFun<T extends readonly unknown[]> = (...params: [...ParamsTuple<T>]) => void
export function debounce<T extends readonly unknown[]>(debounceFun: DebounceFun<T>, timeout = 1000): DebounceFun<T> {
  let timer = 0
  return function (...params: [...ParamsTuple<T>]) {
    if (timer) {
      clearTimeout(timer)
      timer = 0
    }
    timer = window.setTimeout(() => {
      timer = 0
      debounceFun(...params)
    }, timeout)
  }
}
export function uuid(pre = 'u_', len = 6) {
  const seed = 'abcdefhijkmnprstwxyz0123456789',
    maxPos = seed.length
  let rtn = ''
  for (let i = 0; i < len; i++) {
    rtn += seed.charAt(Math.floor(Math.random() * maxPos))
  }
  return pre + rtn
}

export function loadJs(src: string) {
  return new Promise<void>((resolve) => {
    const script = document.createElement('script')
    script.src = src
    script.type = 'text/javascript'
    script.onload = () => {
      resolve()
    }
    script.onerror = () => {
      resolve()
    }
    document.head.append(script)
  })
}

export const makeSetter = (
  key: string,
  convert?: {
    convert?: (data: any, output: any, value: any) => any
    convertBack?: (data: any, value: any) => any
  }
) => {
  return {
    get({ data }: any) {
      return typeof convert?.convertBack == 'function' ? convert.convertBack(data, data[key]) : data[key]
    },
    set({ data, output }: any, val: any[]) {
      data[key] = typeof convert?.convert == 'function' ? convert.convert(data, output, val) : val
    }
  }
}
